Skip to content

[pull] main from MetaMask:main#292

Merged
pull[bot] merged 13 commits into
Reality2byte:mainfrom
MetaMask:main
Nov 3, 2025
Merged

[pull] main from MetaMask:main#292
pull[bot] merged 13 commits into
Reality2byte:mainfrom
MetaMask:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Nov 3, 2025

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

sophieqgu and others added 13 commits November 3, 2025 18:41
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [x] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [x] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Sets the time-remaining clock `Icon` in `ActiveBoosts.tsx` to use
white text color.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9f2249b. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
This PR fixes missing periods at the end of settings descriptions.
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Fixed missing periods at the end of settings
descriptions

## **Related issues**

Fixes: #18521
https://consensyssoftware.atlassian.net/browse/TMCU-122

## **Manual testing steps**

```gherkin
Feature: Go to settings

  Scenario: user goes to settings
    Given user onboarded

    When user navigates to settings
    Then all settings descriptions have periods at the end
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds trailing periods to several settings descriptions in `en.json`
and updates corresponding Jest snapshots.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
297ee4f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**
This PR fixes inconsistent top padding in networks list
<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Fixed inconsistent top padding in networks list

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TMCU-70

## **Manual testing steps**

```gherkin
Feature: Open custom networks list

  Scenario: user opens custom networks list
    Given user onboarded

    When user navigates to activity and clicks networks selector and them "Custom" tab
    Then padding between tabs header and first item is consistent with paddings between items
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**
<img width="414" height="866" alt="Screenshot 2025-11-03 at 12 44 18"
src="https://github.com/user-attachments/assets/67f81fb1-3c6f-4c8e-ac88-c12149bcbac4"
/>

<!-- [screenshots/recordings] -->

### **After**
<img width="409" height="855" alt="Screenshot 2025-11-03 at 12 44 08"
src="https://github.com/user-attachments/assets/51301eec-eda2-4d03-81ea-0f5a910482ea"
/>

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds `paddingVertical: 12` to `CustomNetworkSelector` `container`
style to standardize top spacing in the custom networks list.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d7a0255. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

This fix removes Android's test task for release builds since it doesn't
exist and is not needed for those variants. Tests remains intact for
debug builds. Also added check on generate binary helpers to validate
scheme, flavor, and configuration.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

nightly_exp_builds_pipeline -
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/db618aea-1aee-4596-84c4-53487bac4ef4
nightly_rc_builds_pipeline -
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/4e3bb45e-e7af-41a4-8ded-c46e0b35797e
expo_dev_pipeline -
https://app.bitrise.io/app/be69d4368ee7e86d/pipelines/d0247767-59dd-4ffe-a5fe-e9b405e1bfa0

When an invalid scheme is passed to iOS - 
<img width="738" height="457" alt="image"
src="https://github.com/user-attachments/assets/2eda72cf-9e3e-4f20-9c83-893e5f53f427"
/>

When an invalid configuration is passed to iOS - 
<img width="716" height="444" alt="image"
src="https://github.com/user-attachments/assets/55fa8099-c754-48c8-9d69-c4759b3ea575"
/>

When an invalid configuration is passed to Android - 
<img width="633" height="540" alt="image"
src="https://github.com/user-attachments/assets/49011063-7d41-49a1-bb54-830dcd72641a"
/>

When an invalid flavor is passed to Android - 
<img width="754" height="491" alt="image"
src="https://github.com/user-attachments/assets/61cdfd89-0ea2-4b3d-82db-2edce0c7b44a"
/>


## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Add strict build param validation and remove Android release
AndroidTest task while keeping debug tests and release AAB/checksum
steps.
> 
> - **scripts/build.sh**:
>   - **Build parameter validation**:
> - `generateIosBinary`: Validate `configuration` (`Debug|Release`) and
`scheme` (`MetaMask|MetaMask-QA|MetaMask-Flask`).
> - `generateAndroidBinary`: Validate `configuration` (`Debug|Release`)
and `flavor` (`Prod|Flask|Qa`).
>   - **Android build behavior**:
> - Release: stop assembling `AndroidTest`; only assemble app, then
build AAB and generate checksum.
>     - Debug: continue assembling `AndroidTest` alongside app.
>   - Minor: clearer echo messages and branching for gradle tasks.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
d8dd18f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This pull request adds a new default feature flag configuration for
`rampsUnifiedBuyV1` in the `remoteFeatureFlagsHelper.ts` file. This
feature flag is set with a minimum version and is inactive by default,
allowing tests to override or activate it as needed. No other changes
are included.

- Added a default feature flag entry for `rampsUnifiedBuyV1` with
`minimumVersion` set to `'7.61.0'` and `active` set to `false` in
`DEFAULT_FEATURE_FLAGS_ARRAY`
(`e2e/api-mocking/helpers/remoteFeatureFlagsHelper.ts`).

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Adds Ramps Unified buy v1 feature flag mock to e2e
tests

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2805 

## **Manual testing steps**

N/A

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds default `rampsUnifiedBuyV1` flag (minimumVersion `7.61.0`,
`active: false`) to the e2e remote feature flags helper.
> 
> - **Testing helpers**:
> - Add default `rampsUnifiedBuyV1` flag to
`DEFAULT_FEATURE_FLAGS_ARRAY` in
`e2e/api-mocking/helpers/remoteFeatureFlagsHelper.ts` with
`minimumVersion: '7.61.0'` and `active: false`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
c6df1d2. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Fixes a MM Connect bug that was wrapping the messages from the dapp to
be shaped as if they came from the multichain provider substream. We
should be allowing the dapp side to fully handle that rather than doing
that in the wallet side.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: null

## **Related issues**

See: MetaMask/connect-monorepo#28

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> RPCBridgeAdapter now sends raw messages to BackgroundBridge (no
multichain wrapper), and tests updated to use/expect the new message
shape.
> 
> - **SDKConnectV2**
> - **RPCBridgeAdapter**: Stop wrapping queued requests with `name:
'metamask-multichain-provider'`; forward the original `request` directly
to `client.onMessage`.
> - **Tests**
(`app/core/SDKConnectV2/adapters/rpc-bridge-adapter.test.ts`):
> - Update requests to include `{ name: 'metamask-multichain-provider',
data: ... }` where appropriate and adjust assertions to expect direct
forwarding of the full request object.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
54455cd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This PR syncs the stable branch to main for version 7.57.1.

*Synchronization Process:*

- Fetches the latest changes from the remote repository
- Resets the branch to match the stable branch
- Attempts to merge changes from main into the branch
- Handles merge conflicts if they occur

*File Preservation:*

Preserves specific files from the stable branch:
  - CHANGELOG.md
  - bitrise.yml
  - android/app/build.gradle
  - ios/MetaMask.xcodeproj/project.pbxproj
  - package.json
 
  Indicates the next version candidate of main to 7.59.0


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Updates CHANGELOG for 7.57.1 with two fixes, corrects comparison
links, and normalizes bullet formatting in prior sections.
> 
> - **Documentation**:
>   - **CHANGELOG (`CHANGELOG.md`)**:
>     - Add `7.57.1` section under Fixed:
>       - show edit account bottomsheet on Android when behind keyboard
>       - patch Touchable issue in React Native
>     - Update links:
>       - `[Unreleased]` now compares `v7.57.1...HEAD`
>       - add `[7.57.1]` compare link `v7.57.0...v7.57.1`
> - Normalize bullets/formatting in prior `7.56.x` sections and adjust a
sonar coverage exclusion entry.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
1f3d7b9. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net>
Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
Co-authored-by: Wei Sun <wei.sun@consensys.net>
Co-authored-by: Nicholas Smith <nick.smith@consensys.net>
Co-authored-by: ieow <4881057+ieow@users.noreply.github.com>
Co-authored-by: runway-github[bot] <73448015+runway-github[bot]@users.noreply.github.com>
Co-authored-by: Matthew Grainger <46547583+Matt561@users.noreply.github.com>
Co-authored-by: Micaela <100321200+micaelae@users.noreply.github.com>
Co-authored-by: SteP-n-s <stylianos.panagakos@consensys.net>
Co-authored-by: Micaela Estabillo <micaela.estabillo@consensys.net>
Co-authored-by: Matthew Walsh <matthew.walsh@consensys.net>
Co-authored-by: abretonc7s <107169956+abretonc7s@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Nick Gambino <35090461+gambinish@users.noreply.github.com>
Co-authored-by: Xavier Brochard <xavier.brochard@consensys.net>
Co-authored-by: gantunesr <17601467+gantunesr@users.noreply.github.com>
Co-authored-by: Gaurav Goel <grvgoel19@gmail.com>
Co-authored-by: Nicholas Gambino <nicholas.gambino@consensys.net>
Co-authored-by: Arthur Breton <arthur.breton@consensys.net>
Co-authored-by: sethkfman <Seth.Kaufman@consensys.net>
Co-authored-by: sethkfman <10342624+sethkfman@users.noreply.github.com>
Co-authored-by: Pedro Pablo Aste Kompen <wachunei@gmail.com>
Co-authored-by: infiniteflower <139582705+infiniteflower@users.noreply.github.com>
Co-authored-by: Matthew Grainger <matthew.grainger@consensys.net>
Co-authored-by: himanshuchawla009 <himanshuchawla2014@gmail.com>
Co-authored-by: Nico MASSART <NicolasMassart@users.noreply.github.com>
Co-authored-by: Brian August Nguyen <brianacnguyen@gmail.com>
Co-authored-by: dylanbutler1 <99672693+dylanbutler1@users.noreply.github.com>
Co-authored-by: tommasini <46944231+tommasini@users.noreply.github.com>
Co-authored-by: Vince Howard <vincenguyenhoward@gmail.com>
Co-authored-by: Juanmi <95381763+juanmigdr@users.noreply.github.com>
Co-authored-by: Ganesh Suresh Patra <ganesh.patra@consensys.net>
Co-authored-by: Jyoti Puri <jyotipuri@gmail.com>
Co-authored-by: OGPoyraz <omergoktugpoyraz@gmail.com>
Co-authored-by: Prithpal Sooriya <prithpal.sooriya@consensys.net>
Co-authored-by: Salim TOUBAL <salim.toubal@outlook.com>
Co-authored-by: Cal Leung <cal.leung@consensys.net>
Co-authored-by: Satyajeet Kolhapure <77279246+satyajeetkolhapure@users.noreply.github.com>
Co-authored-by: Jean-Baptiste Blanc <jb.blanc@consensys.net>
Co-authored-by: George Weiler <georgejweiler@gmail.com>
Co-authored-by: Caainã Jeronimo <caainaje@gmail.com>
Co-authored-by: Luis Taniça <matallui@gmail.com>
Co-authored-by: VGR <VanGulckRik@gmail.com>
Co-authored-by: George Marshall <george.marshall@consensys.net>
Co-authored-by: AxelGes <34173844+AxelGes@users.noreply.github.com>
Co-authored-by: Patryk Łucka <patryk.lucka@gmail.com>
Co-authored-by: Davide Brocchetto <davide.brocchetto@consensys.net>
Co-authored-by: Curtis David <Curtis.David7@gmail.com>
Co-authored-by: Monte Lai <monte.lai@consensys.net>
Co-authored-by: Bruno Nascimento <brunonascimentodev@gmail.com>
Co-authored-by: Maarten Zuidhoorn <maarten@zuidhoorn.com>
Co-authored-by: cmd-ob <ola.bale@consensys.net>
Co-authored-by: João <castrofjoao@gmail.com>
Co-authored-by: sophieqgu <sophieqgu@gmail.com>
Co-authored-by: Alejandro Garcia Anglada <aganglada@gmail.com>
Co-authored-by: Mathieu Artu <mathieu.artu@consensys.net>
Co-authored-by: sophieqgu <37032128+sophieqgu@users.noreply.github.com>
Co-authored-by: Charly Chevalier <charlyy.chevalier@gmail.com>
Co-authored-by: Bryan Fullam <8902170+bfullam@users.noreply.github.com>
Co-authored-by: António Regadas <antonio.regadas@consensys.net>
Co-authored-by: Edouard Bougon <15703023+EdouardBougon@users.noreply.github.com>
Co-authored-by: Alex Donesky <adonesky@gmail.com>
Co-authored-by: Baptiste Marchand <75846779+baptiste-marchand@users.noreply.github.com>
Co-authored-by: Fabio Bozzo <fabio.bozzo@gmail.com>
Co-authored-by: Owen Craston <owen.craston@consensys.net>
Co-authored-by: Pavel Dvorkin <pavel.dvorkin@consensys.net>
Co-authored-by: Kevin Bluer <kevin@bluer.com>
Co-authored-by: Nodonisko <suchydan@gmail.com>
Co-authored-by: Tamas <soostamas.hu@gmail.com>
Co-authored-by: ffmcgee <51971598+ffmcgee725@users.noreply.github.com>
Co-authored-by: Alexandre Chappaz <alex@achappaz.fr>
Co-authored-by: Harika <153644847+hjetpoluru@users.noreply.github.com>
Co-authored-by: Erik Nilsson <eriks@mail.se>
Co-authored-by: Patryk Łucka <5708018+PatrykLucka@users.noreply.github.com>
Co-authored-by: Bernardo Garces Chapero <bernardo.chapero@consensys.net>
Co-authored-by: Christian Montoya <christian.montoya@consensys.net>
Co-authored-by: Vinicius Stevam <45455812+vinistevam@users.noreply.github.com>
Co-authored-by: Gauthier Petetin <gauthierpetetin@hotmail.com>
Co-authored-by: João Loureiro <175489935+joaoloureirop@users.noreply.github.com>
Co-authored-by: Xiaoming Wang <7315988+dawnseeker8@users.noreply.github.com>
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
Co-authored-by: Charly Chevalier <charly.chevalier@consensys.net>
Co-authored-by: salimtb <salim.toubal@consensys.net>
Co-authored-by: tommasini <tommasini15@gmail.com>
Co-authored-by: jake-perkins <128608287+jake-perkins@users.noreply.github.com>
## **Description**
wdio/cli cross-spawn package bump to remove an audit issue

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry:

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds `npmAuditIgnoreAdvisories` in `.yarnrc.yml` to ignore cross-spawn
ReDoS advisory `1104663` used via wdio dev dependency.
> 
> - **Tooling/Config**:
> - Update `.yarnrc.yml` to add `npmAuditIgnoreAdvisories` with advisory
`1104663` (cross-spawn ReDoS) and related comments.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
f2b1b6c. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: metamaskbot <metamaskbot@users.noreply.github.com>
…#21685)

<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

Handles progressive quote streaming gracefully
- disables swap tx submission until quotes are fully loaded so the user
can see warnings beforehand
- cancels ongoing tx scan when a new quote is streamed to prevent
overlapping requests
- reduces input debounce time to 300ms
- bumps bridge-controller and bridge-status-controller to latest
versions


<!--
Write a short description of the changes included in this pull request,
also include relevant motivation and context. Have in mind the following
questions:
1. What is the reason for the change?
2. What is the improvement/solution?
-->

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: chore: improve quote streaming UX and prevent premature
tx submission

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/SWAPS-3243

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

When SSE is enabled
1. Get quotes for <$10 of any ethereum token to sol:USDC
2. Wait 30s for quotes to refresh
3. The Swap button should be disabled while quotes are loading
4. Page should only show alerts after quotes are finished loading

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [ ] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [ ] I've completed the PR template to the best of my ability
- [ ] I’ve included tests if applicable
- [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [ ] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Disables swap submission while quotes load, adds abortable Solana
validation to prevent overlapping requests, reduces input debounce to
300ms, and updates @metamask/bridge-controller.
> 
> - **Bridge UX/Logic**:
> - Disables `Confirm` button while quotes are `isLoading` in
`BridgeView/index.tsx`.
> - Adds abortable validation in `useBridgeQuoteData` using
`AbortController`, cancels previous requests on new quotes/unmount, and
guards results via a validation ID.
> - Passes `AbortSignal` to `useValidateBridgeTx` and threads `signal`
through fetch.
> - Lowers quote request debounce to `300ms` in `useBridgeQuoteRequest`.
> - **Messaging/Permissions**:
> - Removes `NetworkController:getState` from delegated actions in
`bridge-controller-messenger`.
> - **Tests**:
> - Updates `useBridgeQuoteData` tests to expect `signal: AbortSignal`
in validation calls.
> - **Dependencies**:
>   - Bumps `@metamask/bridge-controller` to `^56.0.3`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
de66fb0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Bryan Fullam <bryan.fullam@consensys.net>
## **Description**

This pull request introduces a new feature flag system for enabling the
"Ramps Unified Buy V1" functionality, allowing for both build-time and
remote feature flag control, along with robust version gating. It
includes the implementation of selectors, a custom React hook, and
comprehensive unit tests to ensure correct precedence and behavior of
flags and version checks.

Feature flag infrastructure:

* Added new selectors in `rampsUnifiedBuyV1.ts` to retrieve the unified
buy V1 feature flag configuration, including active status and minimum
required version, from remote feature flags.
* Implemented unit tests for these selectors to ensure they handle all
edge cases (e.g., missing, null, or undefined values).

Custom hook for feature enablement logic:

* Created `useRampsUnifiedV1Enabled` hook that determines if the feature
should be enabled, prioritizing the build flag
(`MM_RAMPS_UNIFIED_BUY_V1_ENABLED`) over remote flags, and enforcing a
minimum app version check using `compare-versions`.

Testing and configuration:

* Added comprehensive tests for the `useRampsUnifiedV1Enabled` hook to
validate precedence of build and remote flags, version gating, and edge
cases.
* Updated Babel test configuration to include the new hook and its
tests.


**Build flag**: 


in `.js.env` presence of this flag means overriding the value, to remove
the override just set it to `""`

```
## Unified Buy v1
export MM_RAMPS_UNIFIED_BUY_V1_ENABLED="true"
```

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Add Ramps Unified Buy feature flag

## **Related issues**

Fixes: https://consensyssoftware.atlassian.net/browse/TRAM-2803

## **Manual testing steps**

N/A


## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.


<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Adds selectors and a hook to enable Ramps Unified Buy V1 via
build/remote flags with minimum-version checks, plus tests and Babel
config updates.
> 
> - **Feature flags**:
> - Add selectors `selectRampsUnifiedBuyV1Config`,
`selectRampsUnifiedBuyV1ActiveFlag`,
`selectRampsUnifiedBuyV1MinimumVersionFlag` in
`app/selectors/featureFlagController/ramps/rampsUnifiedBuyV1.ts`.
> - **Hook**:
> - Implement `useRampsUnifiedV1Enabled` in
`app/components/UI/Ramp/hooks/useRampsUnifiedV1Enabled.ts` with build
flag (`MM_RAMPS_UNIFIED_BUY_V1_ENABLED`) precedence and
`compare-versions` minimum-version gating.
> - **Tests**:
> - Add unit tests for selectors and hook covering flag precedence and
version edge cases.
> - **Config**:
> - Update `babel.config.tests.js` to exclude the new hook/tests from
env var inlining.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
8274e81. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
…g active tab (#21822)

## **Description**

This PR simplifies the `TabsList` component by removing complex
ScrollView-based tab navigation in favor of a lightweight gesture-based
approach.

**What is the reason for the change?**

The previous `TabsList` implementation had significant complexity that
was unnecessary for the wallet page use case:
- Heavy ScrollView with horizontal paging and complex scroll handling
- Multiple refs, timeouts, and state management for scroll coordination
- Complex height measurement logic with debouncing and timing constants
- Adjacent tab preloading logic
- Over 1,600 lines of code across implementation and tests

This complexity caused:
- Difficult maintenance and debugging
- Performance overhead from scroll event handlers
- Conflicts with page-level scrolling in the wallet redesign
- Flaky tests due to timing-dependent behavior

**What is the improvement/solution?**

This PR dramatically simplifies TabsList by:

1. **Replacing ScrollView with gesture-based navigation** using
`react-native-gesture-handler`
   - Pan gestures detect swipe left/right
   - Direct tab switching with `hidden` CSS class
   - No scroll event coordination needed

2. **Simplifying tab rendering**
   - Removed horizontal ScrollView and paging logic
   - Uses simple show/hide with `hidden` class
   - All tabs render in place, inactive tabs are hidden

3. **Streamlined caching**
   - Only loads the active tab on demand
   - Removed adjacent tab preloading
   - Removed complex timing coordination

4. **Reduced code complexity**
   - **389 lines removed** from TabsList.tsx
   - **1,357 lines removed** from tests
- Removed refs for scroll coordination, timeout management, and
measurement timers
- Removed dependencies: `useTailwind`, `Dimensions`, scroll event types

5. **Improved gesture support**
   - Natural swipe thresholds (50px or 500 velocity)
   - Proper worklet execution with `react-native-reanimated`
   - Skips disabled tabs during swipe navigation

**Benefits:**
- ✅ Simpler, more maintainable code
- ✅ Better compatibility with page-level scrolling
- ✅ No scroll event overhead
- ✅ More reliable tests (no timing dependencies)
- ✅ Cleaner architecture for wallet page integration

## **Changelog**

CHANGELOG entry: Simplified TabsList component with gesture-based
navigation

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/jira/software/c/projects/DSYS/boards/1888?search=tab&selectedIssue=DSYS-247

## **Manual testing steps**

```gherkin
Feature: Simplified TabsList navigation

  Scenario: user swipes between tabs
    Given TabsList with multiple tabs
    
    When user swipes left
    Then next tab displays
    And transition is smooth
    
    When user swipes right
    Then previous tab displays

  Scenario: user taps tabs directly
    Given TabsList with multiple tabs
    
    When user taps a tab button
    Then that tab becomes active immediately
    And only the active tab content loads

  Scenario: disabled tabs are skipped during swipe
    Given TabsList with some disabled tabs
    
    When user swipes through tabs
    Then disabled tabs are skipped
    And only enabled tabs are accessible

  Scenario: lazy loading of tab content
    Given TabsList with 4 tabs
    And user is on first tab
    
    When user switches to third tab
    Then third tab content loads
    And unused tabs remain unloaded
    And no preloading occurs
```

## **Screenshots/Recordings**

### **Before**

### **After**

https://github.com/user-attachments/assets/51537667-68f6-4ed3-8e15-a8a1b0262588

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable (✅ Tests updated to match
simplified implementation)
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

---


<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Refactors TabsList to use pan-gesture navigation and
InteractionManager-driven lazy loading, rendering only loaded/active
tabs and updating tests/snapshots accordingly.
> 
> - **Component `TabsList`**:
> - Replace `ScrollView` paging and scroll handlers with
`GestureDetector` pan gestures; remove scroll refs/timeouts and layout
width logic.
> - Add lazy loading via `InteractionManager.runAfterInteractions`;
cache loaded tabs; render only active/loaded content; skip disabled
tabs; preserve selection by `key` on children changes.
> - Keep ref API (`goToTabIndex`, `getCurrentIndex`); pass through
`tabsBarProps` and testIDs; simplify layout to a single `Box` container.
> - **Tests & Snapshots**:
> - Rewrite tests to mock `InteractionManager`, verify deferred loading,
cancellation, immediate loads for cached tabs, and gesture wrapper
presence.
> - Update/refocus tests on tab press behavior, disabled tabs handling,
ref navigation, dynamic tabs by key, and edge cases (non-React children,
initialActiveIndex).
>   - Refresh snapshots to reflect new structure without `ScrollView`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
2d17260. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
<!--
Please submit this PR as a draft initially.
Do not mark it as "Ready for review" until the template has been
completely filled out, and PR status checks have passed at least once.
-->

## **Description**

This PR introduces a change that keeps the Perps redux subscription
active throughout the app lifecycle. This ensures that things like
`reconnectWithNewContext()` gets triggered automatically when things
like account switches get called. We were noticing that this
reconnection was regressing on some
[PerpsTab](#22044)
refactoring for full page scroll, so this should help mitigate this type
of regression.

I don't think this will introduce any major performance regression. The
Redux subscription is pretty lightweight, and I think we can keep it
alive throughout the app lifecycle. Worth reviewing with @abretonc7s
here though.

## **Changelog**

<!--
If this PR is not End-User-Facing and should not show up in the
CHANGELOG, you can choose to either:
1. Write `CHANGELOG entry: null`
2. Label with `no-changelog`

If this PR is End-User-Facing, please write a short User-Facing
description in the past tense like:
`CHANGELOG entry: Added a new tab for users to see their NFTs`
`CHANGELOG entry: Fixed a bug that was causing some NFTs to flicker`

(This helps the Release Engineer do their job more quickly and
accurately)
-->

CHANGELOG entry: Maintain Perps redux state monitoring throughout app
lifecycle

## **Related issues**

Fixes:

## **Manual testing steps**

```gherkin
Feature: my feature name

  Scenario: user [verb for user action]
    Given [describe expected initial app state]

    When user [verb for user action]
    Then [describe expected outcome]
```

## **Screenshots/Recordings**

<!-- If applicable, add screenshots and/or recordings to visualize the
before and after of your change. -->

### **Before**

<!-- [screenshots/recordings] -->

### **After**

<!-- [screenshots/recordings] -->

## **Pre-merge author checklist**

- [x] I’ve followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I’ve included tests if applicable
- [x] I’ve documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I’ve applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Keeps Perps Redux monitoring active by eliminating
`cleanupStateMonitoring()` during disconnect/grace paths and only
cleaning preloaded subscriptions.
> 
> - **PerpsConnectionManager
(`app/components/UI/Perps/services/PerpsConnectionManager.ts`)**:
>   - **Disconnection flow**:
> - Remove calls to `cleanupStateMonitoring()` during
actual/grace-period disconnection.
> - Keep Redux monitoring active even when disconnecting or not
connected.
> - Continue cleaning only preloaded subscriptions via
`cleanupPreloadedSubscriptions()`.
>   - **Grace period handling**:
> - Drop redundant else-branches that previously cleaned up monitoring
when not connected.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7b92699. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## **Description**

This PR refactors the wallet page scroll architecture to improve
performance and user experience.

**What is the reason for the change?**

Previously, each wallet tab (Tokens, NFTs, DeFi Positions, Predictions)
used virtualized lists (FlashList/FlatList) with individual scroll
containers. This approach caused:
- Performance overhead from multiple virtualized lists
- Complex scroll coordination issues
- Inconsistent scroll behavior across tabs
- Memory overhead from maintaining multiple list states

**What is the improvement/solution?**

This PR consolidates scrolling by:
1. **Enabling scroll at the wallet page level** - The entire wallet page
now scrolls as a single container
2. **Removing scroll from individual tabs** - Each tab (Tokens, NFTs,
DeFi, Predictions) now renders content statically without
FlashList/FlatList when scroll is disabled at the tab level
3. **Adding skeleton loaders** - New skeleton components provide better
loading states (TokenListSkeleton, NftGridSkeleton)
4. **Adding empty state components** - Improved empty state handling
with dedicated components (TokensEmptyState)

The changes affect:
- **Tokens tab**: Replaced FlashList with static rendering when scroll
disabled
- **NFT Grid**: Removed FlashList, uses ScrollView-compatible layout
- **DeFi Positions**: Removed FlatList in favor of direct rendering
- **Predictions tab**: Removed FlashList, uses static layout
- **Wallet page**: Added ScrollView wrapper for unified scrolling

This architecture pairs with the TabsList auto-height capability (in
`fix/tab-individual-height`) to allow each tab to display all content
with the page-level scroll handling navigation between sections.

## **Changelog**

CHANGELOG entry: Improved wallet page scrolling performance by
consolidating scroll behavior at the page level

## **Related issues**

Fixes:
https://consensyssoftware.atlassian.net/jira/software/c/projects/DSYS/boards/1888?selectedIssue=DSYS-250

## **Manual testing steps**

```gherkin
Feature: Wallet page scroll improvements

  Scenario: user scrolls through wallet tabs
    Given user is on the Wallet page with tokens
    
    When user scrolls down
    Then the entire page scrolls smoothly
    And all tabs remain accessible
    And tab content loads without flickering

  Scenario: user switches between tabs
    Given user is on the Wallet page
    
    When user taps on different tabs (Tokens, NFTs, DeFi, Predictions)
    Then each tab displays content without FlashList artifacts
    And scroll position resets appropriately per tab
    And tab transitions are smooth

  Scenario: user views empty states
    Given user has no tokens/NFTs/positions
    
    When user navigates to empty tabs
    Then appropriate empty state messages display
    And layout remains stable

  Scenario: user views loading states
    Given wallet data is loading
    
    When user opens the wallet page
    Then skeleton loaders display for each tab
    And transitions to actual content are smooth
```

## **Screenshots/Recordings**
### **Before**

https://github.com/user-attachments/assets/28e93320-e519-4fc4-860f-1e5477d90bb9

https://github.com/user-attachments/assets/912fd548-c613-4fb5-9b5b-8dd864f20d2d

### **After**
When homepage redesign feature flag V1 is false
- Tokens Tab 

https://github.com/user-attachments/assets/15809592-6066-48ee-a8b7-2af0a03cdb55

- NFTs Tab 

https://github.com/user-attachments/assets/8b821113-fcf8-4416-a629-740571d49d59

- Perps Tab 

https://github.com/user-attachments/assets/b364311c-6162-4f2a-bfbc-476daea5587a

- Defi Tab 

https://github.com/user-attachments/assets/c59acab7-0cfa-4a75-92c5-4eb0bcd7b2a3

- Predictions Tab 

https://github.com/user-attachments/assets/1f584e55-a0fd-40d9-9942-7ceb5335837f



When homepage redesign feature flag V1 is true
- Tokens Tab 

https://github.com/user-attachments/assets/c10f0f2a-aa50-4f38-be42-b65d7f28d521

- NFTs Tab 

https://github.com/user-attachments/assets/0263d21c-0bbc-4e57-8784-37eeecbdea60

- Perps Tab 

https://github.com/user-attachments/assets/602db546-455c-462b-ab87-8f74624d0d73

- Defi Tab 

https://github.com/user-attachments/assets/4a154aae-2245-42dd-bdca-e19a15eea68b

- Predictions Tab

https://github.com/user-attachments/assets/8fdfeeed-3cee-4ec2-b627-3fd8fe966166

<!-- Add recordings showing the new unified scroll behavior -->

## **Pre-merge author checklist**

- [x] I've followed [MetaMask Contributor
Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile
Coding
Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md).
- [x] I've completed the PR template to the best of my ability
- [x] I've included tests if applicable
- [x] I've documented my code using [JSDoc](https://jsdoc.app/) format
if applicable
- [x] I've applied the right labels on the PR (see [labeling
guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)).
Not required for external contributors.

## **Pre-merge reviewer checklist**

- [ ] I've manually tested the PR (e.g. pull and build branch, run the
app, test code being changed).
- [ ] I confirm that this PR addresses all acceptance criteria described
in the ticket it closes and includes the necessary testing evidence such
as recordings and or screenshots.



<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> Enables global wallet scrolling and refactors
Tokens/NFTs/DeFi/Perps/Predict tabs to render without inner scroll
(behind homepageRedesignV1), adding skeleton loaders and empty states.
> 
> - **Wallet**:
> - **Global Scroll**: Wraps wallet content in `ConditionalScrollView`
(new) to enable page-level scrolling; tabs pass content without inner
scroll when `homepageRedesignV1` is enabled.
> - **New Components**:
>   - `components-temp/ConditionalScrollView` (+ types, tests).
>   - `TokensEmptyState` and `TokenListSkeleton`; `NftGridSkeleton`.
> - **Tabs Refactor (flag-driven)**:
> - **Tokens**: `TokenList` renders items directly (no `FlashList`) when
not full view; adds skeleton and empty state; simplifies `Tokens`
(removes progressive loader) and applies `maxItems` (10) for homepage
redesign.
> - **NFTs**: `NftGrid` renders grid directly or via `FlashList` in full
view; adds skeleton, limits to 18 items with "View all"; UI tweaks in
`NftGridItem`.
> - **DeFi Positions**: Replace `FlatList` with direct render; optional
scroll via `ConditionalScrollView` and new testID for scroll view.
> - **Perps**: Use `ConditionalScrollView`; loading skeleton layout
adapts to flag.
> - **Predict**: Replace `FlashList` with direct render;
`PredictTabView` uses `ConditionalScrollView`.
> - **UI/Styling**:
> - Centered `CollectibleMedia` fallback text; minor layout cleanups;
token header back button `testID`.
> - **Tests & E2E**:
> - Extensive unit test updates for new render/flag behavior; add
skeleton/empty-state tests; update selectors (e.g.,
`DEFI_POSITIONS_SCROLL_VIEW`) and e2e token matcher to fetch first
instance.
> - **Localization**:
>   - Adds `wallet.tokens_empty_description`.
> 
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
6bedb5f. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
@pull pull Bot locked and limited conversation to collaborators Nov 3, 2025
@pull pull Bot added the ⤵️ pull label Nov 3, 2025
@pull pull Bot merged commit 0c80dc9 into Reality2byte:main Nov 3, 2025
1 check failed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants